﻿//*****************************************************************************
//
//  Copyright 2008 IT Cloud Company
//
//  This software is available under the Microsoft Public License.  Please
//  read the license agreement at http://opensource.org/licenses/ms-pl.html
//  before using the software.
//
//  Authors:
//    Don Song (don@itcloud.com)
//
//*****************************************************************************

using System;
using System.Collections.Generic;
using System.Text;
using HeadLinx.AD.Explorer.Properties;
using Microsoft.Win32;
using System.IO;
using HeadLinx.AD.Common;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.IO.Packaging;
using System.Windows.Xps.Packaging;
using System.Windows.Xps;
using System.Windows.Markup;

namespace HeadLinx.AD.Explorer
{
    /// <summary>
    /// Utility functions local to this project (do not mark public).
    /// </summary>
    static class LocalUtility
    {
        public static SaveFileDialog GetSaveFileDialog()
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.AddExtension = true;
            dlg.CheckFileExists = false;
            dlg.CheckPathExists = true;
            dlg.CreatePrompt = false;
            dlg.DereferenceLinks = false;
            dlg.FilterIndex = 0;
            dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            dlg.OverwritePrompt = true;
            dlg.RestoreDirectory = false;
            dlg.ValidateNames = true;
            return dlg;
        }

        public static void LoadInitialDialogFolder(FileDialog dlg)
        {
            if (Directory.Exists(Settings.Default.LastChartFolder))
            {
                dlg.InitialDirectory = Settings.Default.LastChartFolder;
            }
            else
            {
                dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            }
        }

        public static void SaveInitialDialogFolder(FileDialog dlg)
        {
            Settings.Default.LastChartFolder = System.IO.Path.GetDirectoryName(dlg.FileName);
            Settings.Default.Save();
        }

        private static string _runAsAlias = null;

        public static string GetCurrentUserAlias()
        {
            if (String.IsNullOrEmpty(_runAsAlias))
            {
                return Environment.UserName;
            }

            return _runAsAlias;
        }

        public static void SetCurrentUserAlias(string runAsAlias)
        {
            _runAsAlias = runAsAlias;
        }

        public static void RunQueryAndShowResults(FrameworkElement parentDialog,
            HeadLinxQueryType queryType, string personNames, string title, bool block)
        {
            try
            {
                if (parentDialog != null)
                {
                    parentDialog.Cursor = Cursors.Wait;
                }

                //
                //  Kick off async query, but block until its finished.
                //
                CreateChartDialog dlg = new CreateChartDialog(App.PhotoCache, queryType);

                dlg.SelectedNames = personNames;
                dlg.ShowPhotos = true; // TODO: chkShowPhotos.IsChecked.Value;
                dlg.ForcePhotoCacheRefresh = false; // TODO: chkForcePhotoCacheRefresh.IsChecked.Value;

                bool? result = dlg.ShowDialog(); // Show progress dialog modally.

                if (parentDialog != null)
                {
                    parentDialog.Cursor = null;
                }

                if (result ?? result.Value)
                {
                    ChartView view = new ChartView(dlg.RootUser, title);

                    if (block)
                    {
                        view.ShowDialog(); // Show chart and block.
                    }
                    else
                    {
                        view.Show(); // Show chart and return.
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error creating chart");
            }
            finally
            {
                if (parentDialog != null)
                {
                    parentDialog.Cursor = null;
                }

                // Always turn off the force photo cache refresh option after
                // every run.  Typically you want to do this once, and its a
                // bad experience to accidentally refresh every time.
                // TODO: chkForcePhotoCacheRefresh.IsChecked = false;
            }
        }

        public static string GetUserBannerName(HeadLinxUser user)
        {
            return String.Format("{0} {1} ({2})",
                user.FirstName, user.LastName, user.EmailAlias);
        }

        private static void ClipAllInformation_Internal(HeadLinxUser user, StringBuilder sb, bool recurse)
        {
            sb.AppendLine("Name: " + GetUserBannerName(user));

            // Basic info
            sb.AppendLine("Title: " + user.Title);
            sb.AppendLine("Company: " + user.Company);
            sb.AppendLine("Department: " + user.Department);

            // Contact info
            sb.AppendLine("Office: " + user.PhysicalOffice);
            sb.AppendLine("Phone: " + user.Phone);
            sb.AppendLine("Mobile: " + user.MobilePhone);

            if (recurse)
            {
                foreach (HeadLinxUser child in user.DirectReports.Values)
                {
                    sb.AppendLine();
                    ClipAllInformation_Internal(child, sb, recurse);
                }
            }
        }

        private static void ClipContactInformation_Internal(HeadLinxUser user, StringBuilder sb, bool recurse)
        {
            sb.AppendLine("Name: " + GetUserBannerName(user));

            // Contact info
            sb.AppendLine("Office: " + user.PhysicalOffice);
            sb.AppendLine("Phone: " + user.Phone);
            sb.AppendLine("Mobile: " + user.MobilePhone);

            if (recurse)
            {
                foreach (HeadLinxUser child in user.DirectReports.Values)
                {
                    sb.AppendLine();
                    ClipContactInformation_Internal(child, sb, recurse);
                }
            }
        }

        public static void ClipAllInformation(HeadLinxUser user, bool recurse)
        {
            StringBuilder sb = new StringBuilder();

            ClipAllInformation_Internal(user, sb, recurse);

            Clipboard.SetText(sb.ToString());
        }

        public static void ClipContactInformation(HeadLinxUser user, bool recurse)
        {
            StringBuilder sb = new StringBuilder();

            ClipContactInformation_Internal(user, sb, recurse);

            Clipboard.SetText(sb.ToString());
        }

        public static void LoadAndShowChartFile(string fileName, bool block)
        {
            HeadLinxUser rootUser;

            using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                rootUser = HeadLinxUser.LoadFromXml(fs);
            }

            ChartView view = new ChartView(rootUser, "File: " + fileName);

            if (block)
            {
                view.ShowDialog(); // Show chart and block until closed.
            }
            else
            {
                view.Show(); // Show chart and return.
            }
        }

        /// <summary>
        /// Saves a canvas to an output file in PNG image format.
        /// </summary>
        /// <param name="canvas"></param>
        /// <param name="outputFile"></param>
        public static void SaveCanvasToPNG(Canvas canvas, string outputFile)
        {
            // Save current layout and reset it.
            Transform savedTransform = canvas.LayoutTransform;
            canvas.LayoutTransform = null;

            Size size = new Size(canvas.Width, canvas.Height);
            canvas.Measure(size);
            canvas.Arrange(new Rect(size));

            RenderTargetBitmap targetBitmap = new RenderTargetBitmap(
                (int)size.Width, (int)size.Height, 96d, 96d, PixelFormats.Default); // PixelFormats.Pbgra32

            targetBitmap.Render(canvas);

            using (FileStream outputStream = new FileStream(outputFile, FileMode.Create))
            {
                PngBitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(targetBitmap));
                encoder.Save(outputStream);
            }

            // Restore layout.
            canvas.LayoutTransform = savedTransform;
        }

        /// <summary>
        /// Saves a canvas to an output file in XPS format.
        /// </summary>
        /// <param name="canvas"></param>
        /// <param name="outputFile"></param>
        public static void SaveCanvasToXPS(Canvas canvas, string outputFile)
        {
            // Save current layout and reset it.
            Transform savedTransform = canvas.LayoutTransform;
            canvas.LayoutTransform = null;

            Size size = new Size(canvas.Width, canvas.Height);
            canvas.Measure(size);
            canvas.Arrange(new Rect(size));

            using (Package package = Package.Open(outputFile, FileMode.Create))
            {
                using (XpsDocument doc = new XpsDocument(package))
                {
                    XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
                    writer.Write(canvas);
                }
            }

            // Restore layout.
            canvas.LayoutTransform = savedTransform;
        }

        /// <summary>
        /// Saves a canvas to XAML.
        /// NOTE: this is not useful yet because the resulting file cannot be viewed
        /// in a standalone viewer.
        /// </summary>
        /// <param name="canvas"></param>
        /// <param name="outputFile"></param>
        public static void SaveCanvasToXAML(Canvas canvas, string outputFile)
        {
            using (FileStream outputStream = new FileStream(outputFile, FileMode.Create))
            {
                XamlWriter.Save(canvas, outputStream);
            }
        }
    }
}
